package com.jaychen.spring.factory.config;

import com.jaychen.spring.core.ioc.BeanDefinition;
import com.jaychen.spring.core.ioc.BeanReference;
import com.jaychen.spring.core.ioc.PropertyValue;
import com.jaychen.spring.utils.CollectionUtils;

import java.lang.reflect.Field;
import java.util.List;

/**
 * 可自动装配内容的BeanFactory
 *
 * @Author Jay Chen
 * @Date 2020/11/9 12:54
 */
public class AutowireCapableBeanFactory extends AbstractBeanFactory {

    @Override
    protected Object doCreateBean(BeanDefinition beanDefinition) throws Exception {
        Object bean = beanDefinition.getBeanClass().newInstance();
        beanDefinition.setBean(bean);
        applyPropertyValues(bean, beanDefinition);
        return bean;
    }

    /**
     * 利用反射将属性赋值给bean对象
     *
     * @param bean
     * @param beanDefinition
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    private void applyPropertyValues(Object bean, BeanDefinition beanDefinition) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
        List<PropertyValue> propertyValues = beanDefinition.getPropertyValues().getPropertyValueList();
        if (CollectionUtils.isBank(propertyValues)) {
            return;
        }
        for (PropertyValue propertyValue : propertyValues) {
            Field field = bean.getClass().getDeclaredField(propertyValue.getName());
            field.setAccessible(true);
            Object value = propertyValue.getValue();
            if (value instanceof BeanReference) {
                // 初始化依赖的bean
                BeanReference beanReference = (BeanReference) value;
                value = getBean(beanReference.getName());
                beanReference.setBean(value);
            }
            field.set(bean, value);
        }
    }
}
